import { Enum } from "cc";
import { color } from "cc";
import { deepclone } from "../../../scripts/libs/utils/deepclone/deepclone";

export const Colors = {
    0: color().fromHEX('#555555'),
    1: color().fromHEX('#ff4c4c'), // 红
    2: color().fromHEX('#6aed16'), // 草绿
    3: color().fromHEX('#ffd71c'), // 黄
    4: color().fromHEX('#17acff'), // 蓝
    5: color().fromHEX('#fa189a'), // 玫色
    6: color().fromHEX('#ff880f'), // 橙
    7: color().fromHEX('#c67ce4'), // 灰紫
    8: color().fromHEX('#02f2ff'), // 青
    9: color().fromHEX('#38e8a2'), // 浅绿

    11: color().fromHEX('#ff4c4c'), // 红
    12: color().fromHEX('#6aed16'), // 草绿
    13: color().fromHEX('#ffd71c'), // 黄
    14: color().fromHEX('#17acff'), // 蓝
    15: color().fromHEX('#fa189a'), // 玫色
    16: color().fromHEX('#ff880f'), // 橙
    17: color().fromHEX('#c67ce4'), // 灰紫
    18: color().fromHEX('#02f2ff'), // 青
    19: color().fromHEX('#38e8a2'), // 浅绿

    90: color().fromHEX('#32712c'), // 祖母绿
    91: color().fromHEX('#34abb0'), //浅蓝
    92: color().fromHEX('#916d2a'), //土黄
    93: color().fromHEX('#398dd8'), //天蓝
    94: color().fromHEX('#799728'), //青绿
    95: color().fromHEX('#194f5e'), //肉
}

export function isClaw(colorId: number) {
    if (colorId >= 11 && colorId <= 19) return true;
    return false;
}

export function oriColor(colorId: number) {
    return colorId % 10;
}

export enum CellType {
    Empty = 0, // 空位
    Block = 1, // 可操作的积木
    Glass = 2, // 玻璃
    Wall = 3, // 墙
}

export enum AxisLockType {
    None = 0,
    Horizontal = 1,
    Vertical = 2,
}
Enum(AxisLockType);

export const AxisLockTypeTxt = ['None', '↔️', '↕️'];

export type BlockType = {
    id: number,
    pos: number,
    shape: number,
    color: number,
    axisLock: AxisLockType,
    axisLockParam: string,
    layer: number,
    group: number,
    ice: number, // 冰
    blind: number, // 问号（盲）
    noBlindTxt: number, // 0正常显示 1隐藏问号值显示
    keys: number[],
    locker: number, // 对应key 颜色
}

export type ArrowType = {
    id: number,
    pos: number,
    color: number,
    direction: number,
    layer: number,
    prev: number, // 前置 Arrow，如果设置了这个项，那么必须先消除该值所指定的箭头才能开启
    ice: number,
}

export type GlassType = {
    id: number,
    pos: number,
    shape: number,
    nails: number[],
    layer: number, // 顺序，数值越大越靠前面
    lock: number, // 锁定值
}

export type StageInfo = {
    stageId: number;
    width: number;
    height: number;
    walls: number[]; // 数组里面是所有墙的坐标
    blocks: BlockType[];
    arrows: ArrowType[];
    glasses: GlassType[];
    barriers: number[][]; // 数组里面是 路障的 0坐标点 1颜色号
    time?: number;
    hard?: number;
    tip?: string;
}

export const dirArrowTxt = ['→', '↑', '←', '↓'];


export type ShapeInfo = {
    shapeId?: number,
    data: number[][],
    tex: string[], // 图片编号组
    c?: number[], // 视觉平衡的中间位置偏移 一定在实体上
    size?: number[], // 最大矩形外边框 [行数,列数]
    center?: number[], // 中心点格号 (可能出现半格) 可能在实体边界或实体外
    axislock?: string[][],
    chainTex?: string,
}

export const shapeInfoMap = new Map<number, ShapeInfo>([
    [0, {
        data: [],
        tex: [],
    }],
    [1, {
        data: [[0, 0]],
        tex: ['0000|0'],
        axislock: [
            ['1|0|0|0'], // 横向锁定：使用tex axislock1, 对应row0,col0，旋转方向0
            ['1|0|0|1'], // 纵向锁定：使用tex axislock1, 对应row0,col0，旋转方向1*90度
        ],
        chainTex: '1x1',
    }],
    [2, {
        data: [[0, 0], [0, 1]],
        tex: ['0011|1', '0011|3'],
        axislock: [
            ['0|0|0|2', '0|0|1|0'],
            ['1|0|.5|1'],
        ],
        chainTex: '1x2',
    }],
    [3, {
        data: [[0, 0], [1, 0]],
        tex: ['0011|0', '0011|2'],
        axislock: [
            ['1|.5|0|0'],
            ['0|0|0|1', '0|1|0|3'],
        ],
        chainTex: '2x1',
    }],
    [4, {
        data: [[0, 0], [0, 1], [0, 2]],
        tex: ['0011|1', '1111|0', '0011|3'],
        axislock: [
            ['0|0|0|2', '0|0|2|0'],
            ['1|0|1|1'],
        ],
        chainTex: '1x3',
    }],
    [5, {
        data: [[0, 0], [1, 0], [2, 0]],
        tex: ['0011|0', '1111|0', '0011|2'],
        axislock: [
            ['1|1|0|0'],
            ['0|0|0|1', '0|2|0|3']
        ],
        chainTex: '3x1',
    }],
    [6, {
        data: [[0, 0], [0, 1], [1, 0]],
        tex: ['0111|1', '0011|3', '0011|2'],
        c: [0, 0],
        axislock: [
            ['0|0|0|2', '0|0|1|0'],
            ['0|0|0|1', '0|1|0|3'],
        ]
    }],
    [7, {
        data: [[0, 0], [1, 0], [1, 1]],
        tex: ['0011|0', '0111|2', '0011|3'],
        c: [1, 0],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['0|0|0|1', '0|1|0|3'],
        ]
    }],
    [8, {
        data: [[0, 1], [1, 0], [1, 1]],
        tex: ['0011|0', '0011|1', '0111|3'],
        c: [1, 1],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [9, {
        data: [[0, 0], [0, 1], [1, 1]],
        tex: ['0011|1', '0111|0', '0011|2'],
        c: [0, 1],
        axislock: [
            ['0|0|0|2', '0|0|1|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [10, {
        data: [[0, 0], [0, 1], [0, 2], [0, 3]],
        tex: ['0011|1', '1111|0', '1111|0', '0011|3'],
        axislock: [
            ['0|0|0|2', '0|0|3|0'],
            ['1|0|1.5|1']
        ]
    }],
    [11, {
        data: [[0, 0], [1, 0], [2, 0], [3, 0]],
        tex: ['0011|0', '1111|0', '1111|0', '0011|2'],
        axislock: [
            ['1|1.5|0|0'],
            ['0|0|0|1', '0|3|0|3'],
        ]
    }],
    [12, {
        data: [[0, 0], [0, 1], [0, 2], [1, 0]],
        tex: ['0111|1', '1111|0', '0011|3', '0011|2'],
        c: [0, 1],
        axislock: [
            ['0|0|0|2', '0|0|2|0'],
            ['0|0|0|1', '0|1|0|3'],
        ]
    }],
    [13, {
        data: [[0, 0], [1, 0], [2, 0], [2, 1]],
        tex: ['0011|0', '1111|0', '0111|2', '0011|3'],
        c: [1, 0],
        axislock: [
            ['0|2|0|2', '0|2|1|0'],
            ['0|0|0|1', '0|2|0|3'],
        ]
    }],
    [14, {
        data: [[0, 2], [1, 0], [1, 1], [1, 2]],
        tex: ['0011|0', '0011|1', '1111|0', '0111|3'],
        c: [1, 1],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|2|1', '0|1|2|3'],
        ]
    }],
    [15, {
        data: [[0, 0], [0, 1], [1, 1], [2, 1]],
        tex: ['0011|1', '0111|0', '1111|0', '0011|2'],
        c: [1, 1],
        axislock: [
            ['0|0|0|2', '0|0|1|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [16, {
        data: [[0, 0], [1, 0], [1, 1], [1, 2]],
        tex: ['0011|0', '0111|2', '1111|0', '0011|3'],
        c: [1, 1],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|0|1', '0|1|0|3'],
        ]
    }],
    [17, {
        data: [[0, 1], [1, 1], [2, 0], [2, 1]],
        tex: ['0011|0', '1111|0', '0011|1', '0111|3'],
        c: [1, 1],
        axislock: [
            ['0|2|0|2', '0|2|1|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [18, {
        data: [[0, 0], [0, 1], [0, 2], [1, 2]],
        tex: ['0011|1', '1111|0', '0111|0', '0011|2'],
        c: [0, 1],
        axislock: [
            ['0|0|0|2', '0|0|2|0'],
            ['0|0|2|1', '0|1|2|3'],
        ]
    }],
    [19, {
        data: [[0, 0], [0, 1], [1, 0], [2, 0]],
        tex: ['0111|1', '0011|3', '1111|0', '0011|2'],
        c: [1, 0],
        axislock: [
            ['0|0|0|2', '0|0|1|0'],
            ['0|0|0|1', '0|2|0|3'],
        ]
    }],
    [20, {
        data: [[0, 0], [0, 1], [1, 0], [1, 1]],
        tex: ['0111|1', '0111|0', '0111|2', '0111|3'],
        axislock: [
            ['0|.5|0|2', '0|.5|1|0'],
            ['0|0|.5|1', '0|1|.5|3'],
        ],
        chainTex: '2x2',
    }],
    [21, {
        data: [[0, 0], [0, 1], [1, 1], [1, 2]],
        tex: ['0011|1', '0111|0', '0111|2', '0011|3'],
        c: [.5, 1],
        axislock: [
            ['1|.5|1|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [22, {
        data: [[0, 1], [1, 0], [1, 1], [2, 0]],
        tex: ['0011|0', '0111|1', '0111|3', '0011|2'],
        c: [1, .5],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['1|1|.5|1'],
        ]
    }],
    [23, {
        data: [[0, 1], [0, 2], [1, 0], [1, 1]],
        tex: ['0111|1', '0011|3', '0011|1', '0111|3'],
        c: [.5, 1],
        axislock: [
            ['1|.5|1|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [24, {
        data: [[0, 0], [1, 0], [1, 1], [2, 1]],
        tex: ['0011|0', '0111|2', '0111|0', '0011|2'],
        c: [1, .5],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['1|1|.5|1'],
        ]
    }],
    [25, {
        data: [[0, 0], [0, 1], [0, 2], [1, 1]],
        tex: ['0011|1', '1111|0', '0011|3', '0011|2'],
        c: [0, 1],
        axislock: [
            ['0|0|0|2', '0|0|2|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [26, {
        data: [[0, 0], [1, 0], [1, 1], [2, 0]],
        tex: ['0011|0', '1111|0', '0011|3', '0011|2'],
        c: [1, 0],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['0|0|0|1', '0|2|0|3'],
        ]
    }],
    [27, {
        data: [[0, 1], [1, 0], [1, 1], [1, 2]],
        tex: ['0011|0', '0011|1', '1111|0', '0011|3'],
        c: [1, 1],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|1|1', '0|1|1|3'],
        ]
    }],
    [28, {
        data: [[0, 1], [1, 0], [1, 1], [2, 1]],
        tex: ['0011|0', '0011|1', '1111|0', '0011|2'],
        c: [1, 1],
        axislock: [
            ['0|1|0|2', '0|1|1|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [29, {
        data: [[0, 1], [1, 0], [1, 1], [1, 2], [2, 1]],
        tex: ['0011|0', '0011|1', '1111|0', '0011|3', '0011|2'],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [30, {
        data: [[0, 0], [0, 1], [0, 2], [1, 1], [2, 1]],
        tex: ['0011|1', '1111|0', '0011|3', '1111|0', '0011|2'],
        axislock: [
            ['0|0|0|2', '0|0|2|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [31, {
        data: [[0, 1], [1, 1], [2, 0], [2, 1], [2, 2]],
        tex: ['0011|0', '1111|0', '0011|1', '1111|0', '0011|3'],
        axislock: [
            ['0|2|0|2', '0|2|2|0'],
            ['0|0|1|1', '0|2|1|3'],
        ]
    }],
    [32, {
        data: [[0, 2], [1, 0], [1, 1], [1, 2], [2, 2]],
        tex: ['0011|0', '0011|1', '1111|1', '1111|0', '0011|2'],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|2|1', '0|2|2|3'],
        ]
    }],
    [33, {
        data: [[0, 0], [1, 0], [1, 1], [1, 2], [2, 0]],
        tex: ['0011|0', '1111|0', '1111|0', '0011|3', '0011|2'],
        axislock: [
            ['0|1|0|2', '0|1|2|0'],
            ['0|0|0|1', '0|2|0|3'],
        ]
    }],
    [34, {
        data: [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]],
        tex: ['0111|1', '1111|0', '0111|0', '0111|2', '1111|0', '0111|3'],
        axislock: [
            ['0|.5|0|2', '0|.5|2|0'],
            ['0|0|1|1', '0|1|1|3'],
        ],
        chainTex: '2x3',
    }],
    // [34, {
    //     data: [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1], [3, 0], [3, 1]],
    //     tex: ['0111|1', '0111|0', '1111|0', '1111|0', '1111|0', '1111|0', '0111|2', '0111|3'],
    // }],
    // [35, {
    //     data: [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3]],
    //     tex: ['0111|1', '1111|0', '1111|0', '0111|0', '0111|2', '1111|0', '1111|0', '0111|3'],
    // }]
]);

for (let [shapeId, shapeInfo] of shapeInfoMap) {
    shapeInfo.shapeId = shapeId;
    let size = [0, 0];
    for (let i = 0; i < shapeInfo.data.length; i++) {
        let dataItem = shapeInfo.data[i];
        if (dataItem[0] + 1 > size[0]) size[0] = dataItem[0] + 1;
        if (dataItem[1] + 1 > size[1]) size[1] = dataItem[1] + 1;
    }
    shapeInfo.size = size;
    shapeInfo.center = [(size[0] - 1) / 2, (size[1] - 1) / 2];
    if (shapeInfo.c == null) {
        shapeInfo.c = shapeInfo.center;
    }
}

export function findShapeId(data: number[][]): number {
    let _data = deepclone(data);
    _data.sort((a, b) => {
        if (a[0] > b[0]) return 1;
        else if (a[0] < b[0]) return -1;
        else {
            return a[1] - b[1];
        }
    });
    for (let [shapeId, shapeInfo] of shapeInfoMap) {
        if (isCongruentArray(_data, shapeInfo.data)) {
            return shapeId;
        }
    }
    return null;
}

export type ChainInfo = {
    shapeId?: number,
    data: number[][],
    tex: string[], // 图片id
}

// 全等二维数组，第二维只有两位长度
export function isCongruentArray(a: number[][], b: number[][]) {
    if (a.length != b.length) return false;
    let length = a.length;
    for (let i = 0; i < length; i++) {
        if (a[i][0] != b[i][0] || a[i][1] != b[i][1]) {
            return false;
        }
    }
    return true;
}

export function genId<T>(map: Map<number, T>, getIdFunc: (t: T) => number): number {
    let idsAlreadyHave = new Set();
    for (let [posId, view] of map) {
        let id = getIdFunc(view);
        if (id != null) {
            idsAlreadyHave.add(id);
        }
    }
    let newId = 0;
    let has = true;
    do {
        has = idsAlreadyHave.has(newId);
        if (!has) {
            return newId;
        }
        newId++;
    } while (has);
}

export const CollisionEdgeOffset = .46;